package be.groept.ace.cursusplanning.model;

import be.groept.ace.cursusplanning.persistency.IPersistentieController;
import be.groept.ace.cursusplanning.persistency.IPersistentieProvider;
import be.groept.ace.cursusplanning.persistency.Persisteerbaar;


/**
 * 
 * @author Gouke
 *
 */

public class CursusHistoriek implements Comparable<CursusHistoriek>, Persisteerbaar {

	
	private String schooljaar;
	private int score = -1;
	private Cursus cursus;
	
	private IPersistentieProvider pProvider;
	/** 
	 * stelt een nieuwe cursushistoriek in
	 * @param schooljaar
	 * @param cursus
	 */
	public CursusHistoriek(Cursus cursus, String schooljaar) throws IllegalArgumentException{
		
		if (cursus == null) throw new IllegalArgumentException("De cursus mag geen null waarde bevatten");
		this.cursus = cursus;
		
		if (!setSchooljaar(schooljaar)){
			throw new IllegalArgumentException("het schooljaar moet ingegeven worden volgens de opmaak= 'JJJJ-JJJJ'");
		}
	}
	/**
	 * geeft de score van de cursist 
	 * @return score als integer
	 */
	public int getScore() {
		return score;
	}
	
	/**
	 * zet de score. 
	 * @param  score 
	 * 			score als integer
	 */
	public void setScore(Integer score) throws IllegalArgumentException{
		
		if (score > this.getCursus().getStudiePunten()){
			throw new IllegalArgumentException("De score kan niet hoger zijn dan het maximum van de stuidiepunten van de cursus");
		}
		this.score = score;
	}

	/**
	 * geeft het schooljaar 
	 * @return schooljaar als string
	 */
	public String getSchooljaar() {
		return this.schooljaar;
	}
	
	/**
	 * geeft de cursus
	 * @return Cursus cursus
	 */
	public Cursus getCursus(){
		return this.cursus;
	}
	
	/**
	 * geeft het eersta jaartal van het schooljaar als een integer terug.
	 * @return int schooljaar
	 */
	public int getEersteJaarVanSchooljaar(){
		return Integer.parseInt(schooljaar.substring(0, 4));
	}
	
	/**
	 * Zet het schooljaar na controle op het formaat van de inputputstring.
	 * Aanvaardt enkel een string waar het tweede jaartal volgt op het eerste jaartal.
	 * @param schooljaar
	 * @return bool
	 */
	private boolean setSchooljaar(String schooljaar){
		
		if (schooljaar == null){
			return false;
		}
		
		schooljaar = schooljaar.trim();
		
		if (schooljaar.length() != 9) {return false;}
		
		//controle op het formaat van de inputstring
			// controle eerste jaartal
			for (int i = 0; i < 4 ; i++){
				if ( !Character.isDigit(schooljaar.charAt(i))){ return false;}
			}
			//controle op " - "
			if (!"-".equals(schooljaar.substring(4, 5))){ return false;}
			//controle op tweede jaartal
			for (int i = 5; i < 9 ; i++){
				if ( !Character.isDigit(schooljaar.charAt(i))){return false;}
			}
		//controle op de waarden
		int j1 = Integer.parseInt(schooljaar.substring(0, 4));
		int j2 = Integer.parseInt(schooljaar.substring(5));
		
		if (j2 != j1 + 1){ return false;}
		
		this.schooljaar = schooljaar;
		return true;
	}
	
	/**
	 * geeft terug of een cursist een voldoende behaalde in deze cursushistoriek
	 * @return TRUE indien voldoende
	 */
	public boolean isVoldoende()
	{
		if (this.getScore() >= this.getCursus().getStudiePunten() / 2){
			return true;
		}
		else{
			return false;
		}
	}
	
	/**
	 * hashCode, gebaseerd op Schooljaar en Cursus
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((schooljaar == null) ? 0 : schooljaar.hashCode());
		result = prime * result
				+ ((cursus == null) ? 0 : cursus.hashCode());
		return result;
	}
	
	/**
	 * equals, gebaseerd op Cursus en Schooljaar
	 * @param obj
	 * 		een Object
	 * @return boolean 
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CursusHistoriek other = (CursusHistoriek) obj;
		if (cursus == null) {
			if (other.cursus != null)
				return false;
		} else if (!cursus.equals(other.cursus))
			return false;
		if (schooljaar == null) {
			if (other.schooljaar != null)
				return false;
		} else if (!schooljaar.equals(other.schooljaar))
			return false;
		return true;
	}

	/**
	 * Positief indien this. schooljaar eerder komt als other.schooljaar
	 * indien de schooljaren gelijk zijn aan elkaar krijgen
	 * we een positief resultaat indien this.cursusNaam vroeger komt in het alfabet.
	 * De score heeft geen invloed op deze methode
	 * @param other
	 * 		een CursusHistoriek
	 * @return int resultaat
	 */
	@Override
	public int compareTo(CursusHistoriek other) {
		return  this.hashCode() - other.hashCode();
	}
	
	@Override
	public Object[] getInfoToBeSaved(IPersistentieController pController) {
		return pProvider.getInfoToBeSaved(pController);
	}
	public IPersistentieProvider getPersistentieProvider(){
		return pProvider;
	}
	public void setPersistentieProvider(IPersistentieProvider provider){
		this.pProvider = provider;
	}

}
